﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using CommonClasses;
using System.Collections.ObjectModel;
using System.Windows.Input;

namespace WpfCardGame.ViewModel
{
    class BJViewModel : ViewModelBase
    {
        #region "Fields and Properties"
        private BJGame _Game = new BJGame();
        public BJGame Game
        {
            get
            {
                return _Game;
            }
            set
            {
                _Game = value;
                RaisePropertyChanged(() => Game);
            }
        }

        private bool _NewGameButtonEnabled;
        public bool NewGameButtonEnabled
        {
            get
            {
                return _NewGameButtonEnabled;
            }
            set
            {
                _NewGameButtonEnabled = value;
                RaisePropertyChanged(() => NewGameButtonEnabled);
            }
        }

        private bool _DealButtonEnabled;
        public bool DealButtonEnabled
        {
            get
            {
                return _DealButtonEnabled;
            }
            set
            {
                _DealButtonEnabled = value;
                RaisePropertyChanged(() => DealButtonEnabled);
            }
        }

        private bool _HitMeButtonEnabled;
        public bool HitMeButtonEnabled
        {
            get
            {
                return _HitMeButtonEnabled;
            }
            set
            {
                _HitMeButtonEnabled = value;
                RaisePropertyChanged(() => HitMeButtonEnabled);
            }
        }

        private bool _StandButtonEnabled;
        public bool StandButtonEnabled
        {
            get
            {
                return _StandButtonEnabled;
            }
            set
            {
                _StandButtonEnabled = value;
                RaisePropertyChanged(() => StandButtonEnabled);
            }
        }

        private string _DealerTotal;
        public string DealerTotal
        {
            get
            {
                return _DealerTotal;
            }
            set
            {
                _DealerTotal = value;
                RaisePropertyChanged(() => DealerTotal);
            }
        }

        private string _PlayerTotal;
        public string PlayerTotal
        {
            get
            {
                return _PlayerTotal;
            }
            set
            {
                _PlayerTotal = value;
                RaisePropertyChanged(() => PlayerTotal);
            }
        }

        private string _Status;
        public string Status
        {
            get
            {
                return _Status;
            }
            set
            {
                _Status = value;
                RaisePropertyChanged(() => Status);
            }
        }

        private ObservableCollection<Card> _DealersCards;
        public ObservableCollection<Card> DealersCards
        {
            get
            {
                return _DealersCards;
            }
            set
            {
                _DealersCards = value;
                RaisePropertyChanged(() => DealersCards);
            }
        }

        private ObservableCollection<Card> _PlayersCards;
        public ObservableCollection<Card> PlayersCards
        {
            get
            {
                return _PlayersCards;
            }
            set
            {
                _PlayersCards = value;
                RaisePropertyChanged(() => PlayersCards);
            }
        }
         
        public ICommand NewGameCommand { get; private set; }
        public ICommand DealCommand { get; private set; }
        public ICommand HitMeCommand { get; private set; }
        public ICommand StandCommand { get; private set; }
        #endregion

        #region "Constructors"
        public BJViewModel()
        {
            NewGameCommand = new RelayCommand(NewGameMethod);
            DealCommand = new RelayCommand(DealMethod);
            HitMeCommand = new RelayCommand(HitMeMethod);
            StandCommand = new RelayCommand(StandMethod);

            InitializeForm();
        }
        #endregion

        #region "Methods"
        public void InitializeForm()
        {
            Status = String.Empty;
            Status = "Press \"New Game\" to start.";
            NewGameButtonEnabled = true;
            DealButtonEnabled = false;
            HitMeButtonEnabled = false;
            StandButtonEnabled = false;
        }
               
        public void NewGameMethod()
        {
            // Subscribe to events.
            Game.Winner += new BJGame.WinnerEventHandler(GameWinner);
            Game.NotEnoughCards += new BJGame.NotEnoughCardsEventHandler(NotEnoughCards);
            Game.MaxedCards += new BJGame.MaxCardReachedEventHandler(MaxCardsOnHand);

            Status = String.Empty;
            NewGameButtonEnabled = false;
            DealButtonEnabled = true;

            Game.NewGame();
            DealersCards = new ObservableCollection<Card>();
            PlayersCards = new ObservableCollection<Card>();            
        }

        public void DealMethod()
        {
            Status = string.Empty;
            DealButtonEnabled = false;
            HitMeButtonEnabled = true;
            StandButtonEnabled = true;

            Game.Deal();
            DealersCards = Game.dealerHand.CardsInPlay();
            PlayersCards = Game.playerHand.CardsInPlay();
            DealerTotal = Game.dealerHand.Total.ToString();
            PlayerTotal = Game.playerHand.Total.ToString();            
        }

        public void HitMeMethod()
        {
            Game.PlayerMove();
            PlayersCards = Game.playerHand.CardsInPlay();
            PlayerTotal = Game.playerHand.Total.ToString();
        }

        public void StandMethod()
        {
            StandButtonEnabled = false;
            HitMeButtonEnabled = false;
            DealButtonEnabled = true;
            Game.DealersTurn();
            DealersCards = Game.dealerHand.CardsInPlay();
            DealerTotal = Game.dealerHand.Total.ToString();
            Game.Evaluate();
        }

        public void GameWinner(string name, int total)
        {
            DealersCards = Game.dealerHand.CardsInPlay();
            PlayersCards = Game.playerHand.CardsInPlay();
            DealerTotal = Game.dealerHand.Total.ToString();
            PlayerTotal = Game.playerHand.Total.ToString();

            HitMeButtonEnabled = false;
            StandButtonEnabled = false;
            DealButtonEnabled = true;

            if (total > 0)
            {
                Status = String.Format("Winner: {0}   Total: {1}", name, total);
            }
            else
            {
                string busted_hand;
                if (name == Game.playerHand.name)
                {
                    busted_hand = Game.dealerHand.name;
                }
                else
                {
                    busted_hand = Game.playerHand.name;
                }
                Status = String.Format("Winner: {0}   {1} busted!", name, busted_hand);
            }            
        }

        public void NotEnoughCards()
        {
            Game.playerHand = new BJHand();
            Game.dealerHand = new BJHand();

            Status = string.Empty;
            NewGameButtonEnabled = true;
            HitMeButtonEnabled = false;
            StandButtonEnabled = false;
            DealButtonEnabled = false;

            Status = "Less than 10 cards in Deck.";
        }

        public void MaxCardsOnHand()
        {
            Status = string.Empty;
            Status = "5 cards maximum.";
            HitMeButtonEnabled = false;
        }

        #endregion

        //private string name = "BlackJack Game";
        //public string Name
        //{
        //    get
        //    {
        //        return name;
        //    }
        //    set
        //    {
        //        name = value;
        //        RaisePropertyChanged(() => Name);
        //    }
        //}        
    }
}
